package de.mnit.basis.swt.anw;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;

import de.mnit.basis.daten.typ.Klasse;
import de.mnit.basis.fehler.Fehler;
import de.mnit.basis.swt.dialog.SWT_Fehler;
import de.mnit.basis.swt.element.S_SWT_Komponente;
import de.mnit.basis.swt.element.steuer.rollbar.gruppe.bild.deko.SWT_Fenster;
import de.mnit.basis.swt.element.steuer.rollbar.gruppe.bild.deko.S_Fenster;
import de.mnit.basis.sys.event.A_HatZuhoerer;
import de.mnit.basis.sys.event.S_Zuhoerer;


/**
 * @author Michael Nitsche
 */
public abstract class A_MN_Gruppe<TA extends A_MN_Gruppe<?>> extends A_HatZuhoerer<TA> implements S_SWT_Komponente<TA,Composite> { //sollte von A_SWT_Element_Basis erben!

	private S_SWT_Komponente<?,? extends Composite> layout;


	public static void start(Class<? extends A_MN_Gruppe<?>> start, int dx, int dy, Object... parameter) {
		if(parameter==null)
			parameter=new Object[0];
		try {
			final A_MN_Gruppe<?> instanz= Klasse.nInstanz(start, parameter);
			SWT_Fenster f=SWT_Fenster.neu(instanz);
			f.sGroesse(dx,dy);
			f.sTitel(start.getSimpleName());
			f.start();
		}
		catch(Throwable t) {
			SWT_Fehler.zeig(t,true);
		}
	}


	public final Composite erzeugeSWT(Widget vater) {
		Fehler.objekt.wenn_Null(vater);
		this.layout=layout();
		if(this.layout==null)
			Fehler.direkt("Layout ist null!", this.getClass().getName());
		this.layout.erzeugeSWT(vater);
		this.swt().layout();
		initStyle();
		initEvents();
		initIntern();
		return this.swt();
	}

	public Composite swt() {
		return this.layout==null ? null : this.layout.swt();
	}

	// TODO evtl. z.B. auch einen SWT_Knopf erlauben
	protected abstract S_SWT_Komponente<?,? extends Composite> layout();
	protected abstract void initStyle();
	protected abstract void initEvents();

	/** Überschreiben bei Bedarf **/
	protected void initIntern() {}

//	public void sFokus() {
//		swt().setFocus();
//	}

	protected S_Fenster<?> gFenster() {
		return (S_Fenster<?>) swt().getShell().getData();
	}

	//Abkürzung, weil oft verwendet!
	protected final S_Fenster<?> f() {
		return gFenster();
	}

//	protected Display gDisplay()   { return swt().getDisplay(); }
	protected Display gDisplay()   { return Display.getCurrent(); } //TODO Besser als die Zeile darüber, aber macht das Sinn?

	@SuppressWarnings("unchecked")
	protected final TA t = (TA)this;

	protected void PN_Erzeugt() {
		if(erzeugt())
			Fehler.sonstige.da_Untypisch("SWT-Widget ist bereits erzeugt!");
	}

	protected boolean erzeugt() {
		return this.swt()!=null;
	}

	// ZUHOERER

	protected Listener nZStartListener(final String ident) {
		Listener erg=new Listener(){
			public void handleEvent(Event event) {
				zuhoererStart(ident,null);
			}
		};
		return erg;
	}

	protected S_Zuhoerer<Object> nZStartZuhoerer(String ident) {
		return nZStartZuhoerer(ident, Object.class);
	}

	protected <T> S_Zuhoerer<T> nZStartZuhoerer(final String ident, Class<T> typ) {
		S_Zuhoerer<T> erg=new S_Zuhoerer<T>(){
			public void verarbeite(T o) {
				zuhoererStart(ident,null);
			}
		};
		return erg;
	}

}